package cn.zhz.gen.core;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.zhz.gen.base.R;
import cn.zhz.gen.support.EnhanceVelocityTemplateEngine;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * @author ZHZ
 * @date 2022-11-03
 * @apiNote
 */

@Slf4j
public class CustomGenerateStyle {

    private final FastGenerator fastGenerator;

    /**
     * 读取控制台输入内容
     */
    private final Scanner scanner = new Scanner(System.in);

    /**
     * 控制台输入内容读取并打印提示信息
     *
     * @param message 提示信息
     * @return
     */
    private String scannerNext(String message) {
        System.out.println(message);
        String nextLine = scanner.nextLine();
        if (StringUtils.isBlank(nextLine)) {
            // 如果输入空行继续等待
            return scanner.next();
        }
        return nextLine;
    }

    public CustomGenerateStyle(FastGenerator fastGenerator) {
        this.fastGenerator = fastGenerator;
    }

    /**
     * 执行生成之前校验参数
     */
    protected void beforeGenerate() {
        // 全局配置
        FastGlobalConfig fastGlobalConfig = fastGenerator.getFastGlobalConfig();
        if (StrUtil.isBlank(fastGlobalConfig.getAuthor())) {
            fastGlobalConfig.author(scannerNext("请输入作者名称："));
        }
        if (fastGlobalConfig.isEnableModule() && StrUtil.isBlank(fastGlobalConfig.getModuleName())) {
            fastGlobalConfig.moduleName(scannerNext("请输入模块名："));
        }
        if (CollUtil.isEmpty(fastGenerator.getTableNames())) {
            fastGenerator.tableNames(getTables(scannerNext("请输入表名，多个英文逗号分隔（所有输入 all）：")));
        }
        if (StrUtil.isBlank(fastGenerator.getOutputDir())) {
            String outputDir = System.getProperty("user.dir");
            fastGenerator.outputDir(outputDir);
            log.info("文件生成路径未配置，已使用默认路径：{}", outputDir);
        }
        if (StrUtil.isBlank(fastGlobalConfig.getPackageParent())) {
            String packageParent = "cn.zhz.gen";
            fastGlobalConfig.packageParent(packageParent);
            log.info("父级包名未配置，已使用默认包名：{}", packageParent);
        }

        // controller配置
        FastControllerConfig fastControllerConfig = fastGenerator.getFastControllerConfig();

        if (StrUtil.isBlank(fastControllerConfig.getResultPath()) || StrUtil.isBlank(fastControllerConfig.getResultSuccessMethod())) {

            try {
                fastControllerConfig.resultSuccessMethod(R.class, R.class.getDeclaredMethod("ok"));
                log.info("controller统一返回值和成功方法未配置，已使用默认class：{} method：{}", fastControllerConfig.getResultPath(), fastControllerConfig.getResultSuccessMethod());
            } catch (NoSuchMethodException e) {
                log.error("未找到R.ok方法，系统错误。");
            }

        }

        // model配置
        FastModelConfig fastModelConfig = fastGenerator.getFastModelConfig();

        if (StrUtil.isBlank(fastModelConfig.getPageNoProperty())) {
            fastModelConfig.pageNoProperty("current");
            log.info("分页参数<当前页>属性名称未配置，已使用默认属性名称：{} ", fastModelConfig.getPageNoProperty());
        }

        if (StrUtil.isBlank(fastModelConfig.getPageSizeProperty())) {
            fastModelConfig.pageSizeProperty("size");
            log.info("分页参数<每页显示条数>属性名称未配置，已使用默认属性名称：{}", fastModelConfig.getPageSizeProperty());
        }


    }


    /**
     * 控制台交互生成
     */
    protected void generateByConsole() {
        // 全局配置
        FastGlobalConfig fastGlobalConfig = fastGenerator.getFastGlobalConfig();
        // controller配置
        FastControllerConfig fastControllerConfig = fastGenerator.getFastControllerConfig();
        // model配置
        FastModelConfig fastModelConfig = fastGenerator.getFastModelConfig();

        FastAutoGenerator fastAutoGenerator = FastAutoGenerator.create(fastGenerator.getUrl(), fastGenerator.getUsername(), fastGenerator.getPassword());
        Map<String, Object> customMap = new HashMap<>();
        customMap.put("swaggerVersion", fastGlobalConfig.getSwaggerVersion());
        // 是否开启jsonFormat注解解决long类型精度丢失问题
        customMap.put("enableFormat", fastModelConfig.isFormat());
        // 统一返回值实体类全路径
        String controllerResultPath = fastControllerConfig.getResultPath();
        customMap.put("controllerResultPath", controllerResultPath);
        // 统一返回值实体类全路径
        customMap.put("controllerResultClassName", controllerResultPath.substring(controllerResultPath.lastIndexOf(StringPool.DOT) + 1));
        // 统一返回值成功方法名称
        customMap.put("controllerResultSuccessMethod", fastControllerConfig.getResultSuccessMethod());
        // 统一返回值
        customMap.put("controllerResultMethodPackage", fastControllerConfig.getResultMethodPackage());
        // 分页参数属性
        String pageSizeProperty = fastModelConfig.getPageSizeProperty();
        String pageNoProperty = fastModelConfig.getPageNoProperty();
        Class<?> pageParamClass = fastModelConfig.getPageParamClass();
        customMap.put("pageSizeProperty", pageSizeProperty);
        customMap.put("pageSizePropertyCapital", NamingStrategy.capitalFirst(pageSizeProperty));
        customMap.put("pageNoProperty", pageNoProperty);
        customMap.put("pageNoPropertyCapital", NamingStrategy.capitalFirst(pageNoProperty));
        if (pageParamClass != null) {
            customMap.put("pageParamClassName", pageParamClass.getSimpleName());
            customMap.put("pageParamClassPackage", pageParamClass.getCanonicalName());
        }


        fastAutoGenerator
                // 全局配置
                .globalConfig(builder ->
                        {
                            if (!fastGlobalConfig.isOpenDir()) {
                                builder.disableOpenDir();
                            }
                            if (fastGlobalConfig.isEnableSwagger()) {
                                builder.enableSwagger();
                            }

                            builder
                                    .author(fastGlobalConfig.getAuthor())
                                    .fileOverride()
                                    .outputDir(fastGenerator.getOutputDir() + "/src/main/java");
                        }
                )
                // 包配置
                .packageConfig(builder -> builder
                        .parent(fastGlobalConfig.getPackageParent())
                        .moduleName(fastGlobalConfig.isEnableModule() ? fastGlobalConfig.getModuleName() : "")
                        .entity("model.po")
                        .pathInfo(Collections.singletonMap(OutputFile.mapperXml, fastGenerator.getOutputDir() + "/src/main/resources/mapper"))
                        .other("model")
                )
                // 自定义模板
                .templateConfig(builder -> builder
                                .entity("vm/entity.java")
                                .mapper("vm/mapper.java")
                                .mapperXml("vm/mapper.xml")
                                .service("vm/service.java")
                                .serviceImpl("vm/serviceImpl.java")
                                .controller("vm/controller.java")
//                        .controller("vm/java/controllerNoResult.java")
                )
                // 自定义注入配置
                .injectionConfig(builder -> builder
                        .customMap(customMap)
                        .customFile(MapUtil
                                .builder("vo", "vm/vo.java.vm")
                                .put("insertDto", "vm/insertDto.java.vm")
                                .put("updateDto", "vm/updateDto.java.vm")
                                .put("queryDto", "vm/queryDto.java.vm")
                                .build())
                )
                // 策略配置
                .strategyConfig((scanner, builder) ->
                        {
                            if (fastModelConfig.getBasePoClass() != null) {
                                builder.entityBuilder().superClass(fastModelConfig.getBasePoClass());
                            }
                            builder
                                    .addInclude(fastGenerator.getTableNames())
                                    .addTablePrefix(fastGenerator.getTablePrefix())
                                    .addTableSuffix(fastGenerator.getTableSuffix())
                                    .controllerBuilder().enableRestStyle()
                                    .entityBuilder().formatFileName("%sPo")
                                    .columnNaming(NamingStrategy.underline_to_camel)
                                    .enableLombok()
                                    .mapperBuilder()
                                    .enableMapperAnnotation().formatMapperFileName("I%sMapper")
                                    .build();
                        }
                )
                // 模板引擎
                .templateEngine(new EnhanceVelocityTemplateEngine())
                .execute();


    }

    /**
     * 处理 all 情况
     *
     * @param tables
     * @return
     */
    private static String[] getTables(String tables) {
        return "all".equals(tables) ? new String[]{} : tables.split(",");
    }

}
